home *** CD-ROM | disk | FTP | other *** search
/ Over 1,000 Windows 95 Programs / Over 1000 Windows 95 Programs (Microforum) (Disc 1).iso / 1138 / source.zip / PAPERBOY.BAS < prev    next >
BASIC Source File  |  1995-05-15  |  17KB  |  494 lines

  1. Option Explicit
  2. ' Global variables
  3. Global PaperboyVersion As String
  4. Global INIfile As String
  5. Global Group As Integer
  6. Global Message As Integer
  7. Global mailsendto As String
  8. Global mailsubject As String
  9. Global mailreferences As String
  10. Global replytype As Integer '1=mail, 2=news
  11. Global Persist As Integer 'Remember position from previous packet
  12.  
  13. ' Windows API used by program
  14. Declare Function GetWinFlags Lib "Kernel" () As Long
  15. Global Const WF_CPU286 = &H2
  16. Declare Function GetProfileInt% Lib "Kernel" (ByVal lpAppName$, ByVal lpKeyName$, ByVal nDefault%)
  17. Declare Function GetProfileString% Lib "Kernel" (ByVal lpAppName$, ByVal lpKeyName$, ByVal lpDefault$, ByVal lpReturnedString$, ByVal nSize%)
  18. Declare Function WriteProfileString% Lib "Kernel" (ByVal lpAppName$, ByVal lpKeyName$, ByVal lpString$)
  19. Declare Function GetPrivateProfileInt% Lib "Kernel" (ByVal lpAppName$, ByVal lpKeyName$, ByVal nDefault%, ByVal lpFileName$)
  20. Declare Function GetPrivateProfileString% Lib "Kernel" (ByVal lpAppName$, ByVal lpKeyName$, ByVal lpDefault$, ByVal lpreturned$, ByVal nSize%, ByVal lpFileName$)
  21. Declare Function WritePrivateProfileString% Lib "Kernel" (ByVal lpAppName$, ByVal lpKeyName$, ByVal lpString$, ByVal lpFileName$)
  22. Declare Function lstrcpy Lib "Kernel" (ByVal lpString1 As Any, ByVal lpString2 As Any) As Long
  23. Declare Function GetModuleUsage% Lib "Kernel" (ByVal hModule%)
  24.  
  25. ' Paperboy/SOUP support DLL API
  26. Global Const ERRMEM = 10
  27. Global Const ERRIO = 20
  28. Global Const ERRPARSE = 30
  29.  
  30. Global Const NUMFOLDERS = 20
  31.  
  32. Type finder
  33.     Group As Integer
  34.     Message As Integer
  35.     lineno As Integer
  36. End Type
  37.  
  38. Declare Function InitSOUPDLL% Lib "PBOYSOUP.DLL" ()
  39. Declare Function MajorVersion% Lib "PBOYSOUP.DLL" ()
  40. Declare Function MinorVersion% Lib "PBOYSOUP.DLL" ()
  41. Declare Function VersionDesc Lib "PBOYSOUP.DLL" () As Long
  42. Declare Function LoadAreas Lib "PBOYSOUP.DLL" (ByVal fname As String) As Integer
  43. Declare Function GetNumAreas Lib "PBOYSOUP.DLL" () As Integer
  44. Declare Function GetAreaName Lib "PBOYSOUP.DLL" (ByVal index As Integer) As Long
  45. Declare Function GetAreaEncoding Lib "PBOYSOUP.DLL" (ByVal index As Integer) As Long
  46. Declare Function GetAreaDesc Lib "PBOYSOUP.DLL" (ByVal index As Integer) As Long
  47. Declare Function GetNumMsgs Lib "PBOYSOUP.DLL" (ByVal index As Integer) As Integer
  48. Declare Function ThreadMsgs Lib "PBOYSOUP.DLL" (ByVal index As Integer) As Integer
  49. Declare Function GetSubject Lib "PBOYSOUP.DLL" (ByVal index As Integer, ByVal index2 As Integer) As Long
  50. Declare Function GetLength Lib "PBOYSOUP.DLL" (ByVal index As Integer, ByVal index2 As Integer) As Long
  51. Declare Function GetAuthor Lib "PBOYSOUP.DLL" (ByVal index As Integer, ByVal index2 As Integer) As Long
  52. Declare Function GetNumLines Lib "PBOYSOUP.DLL" () As Integer
  53. Declare Function GetLine Lib "PBOYSOUP.DLL" (ByVal lineno As Integer) As Long
  54. Declare Function GetInfo Lib "PBOYSOUP.DLL" () As Integer
  55. Declare Function Post Lib "PBOYSOUP.DLL" (ByVal fname As String, ByVal sendtype As Integer) As Integer
  56. Declare Function GetHeader Lib "PBOYSOUP.DLL" (ByVal header As String) As Long
  57. Declare Function GetGMTime Lib "PBOYSOUP.DLL" () As Long
  58. Declare Sub GetMsg Lib "PBOYSOUP.DLL" (ByVal index1 As Integer, ByVal index2 As Integer)
  59. Declare Sub Rot13Msg Lib "PBOYSOUP.DLL" ()
  60. Declare Sub reclaimareas Lib "PBOYSOUP.DLL" ()
  61. Declare Function IsFolder Lib "PBOYSOUP.DLL" (ByVal index As Integer) As Integer
  62. Declare Function LoadFolder Lib "PBOYSOUP.DLL" (ByVal foldername As String, ByVal folderfile As String, ByVal folderdesc As String) As Integer
  63. Declare Sub CreateNewMsg Lib "PBOYSOUP.DLL" ()
  64. Declare Function AddLineToMsg Lib "PBOYSOUP.DLL" (ByVal newline As String) As Integer
  65. Declare Sub RemoveArea Lib "PBOYSOUP.DLL" (ByVal foldername As String)
  66. Declare Function SaveMsgToFolder Lib "PBOYSOUP.DLL" (ByVal filename As String) As Integer
  67. Declare Function DeleteMsg Lib "PBOYSOUP.DLL" (ByVal areaindex As Integer, ByVal msgindex As Integer) As Integer
  68. Declare Function Find Lib "PBOYSOUP.DLL" (begin As finder, ByVal srchstring As String) As Integer
  69. Declare Function GetErrorText Lib "PBOYSOUP.DLL" () As Long
  70.  
  71. Sub CheckCPU ()
  72.     Dim cputype As Long
  73.     
  74.     ' Check for CPU > 286
  75.     cputype = GetWinFlags()
  76.     If cputype And WF_CPU286 Then
  77.         ' Paperboy DLL uses 386 instructions, warn user now
  78.         MsgBox "Paperboy requires a 386SX or greater processor.", MB_OK + MB_ICONSTOP, "Warning!"
  79.         End
  80.     End If
  81. End Sub
  82.  
  83. Sub CreateFolder (foldername As String)
  84. Dim folderfile As String
  85. Dim filenum As Integer
  86. Dim foldernum As Integer
  87.  
  88.     If foldername = "" Then Exit Sub
  89.  
  90.     ' See if folder already exists
  91.     For foldernum = 1 To NUMFOLDERS
  92.         If GetINI("Folders", "Name" + Format$(foldernum), "") = foldername Then
  93.             Exit Sub
  94.         End If
  95.     Next foldernum
  96.     foldernum = 1
  97.  
  98.     ' Find a blank folder slot
  99.     screen.MousePointer = HourGlass
  100.     frmmain.lstsubjects.Enabled = False
  101.     foldernum = 1
  102.     While GetINI("Folders", "Name" + Format$(foldernum), "") <> ""
  103.         foldernum = foldernum + 1
  104.     Wend
  105.     If foldernum > NUMFOLDERS Then
  106.         MsgBox "Too many folders", 0, "Warning!"
  107.     Else
  108.         ' Create the folder
  109.         SetINI "Folders", "Name" + Format$(foldernum), foldername
  110.         ' Create folder file
  111.         folderfile = app.Path + "\FOLDER" + Format$(foldernum) + ".FOL"
  112.         filenum = FreeFile
  113.         Open folderfile For Append As filenum
  114.         Close filenum
  115.     End If
  116.     
  117.     ' Reread folders
  118.     DoFolders
  119.     
  120. End Sub
  121.  
  122. Sub DllErr (ByVal result As Integer)
  123. Dim continue As Integer
  124. Dim msgstr As String
  125.  
  126.     msgstr = fixstr(GetErrorText())
  127.     If result > 0 And result < 100 Then
  128.         If result = ERRMEM Then
  129.             continue = MsgBox(msgstr + Chr$(10) + "Restart to assure reliable operation" + Chr(10) + "Continue?", MB_YESNO + MB_DEFBUTTON1 + MB_ICONSTOP, "PBOYSOUP.DLL: Out of Memory")
  130.         End If
  131.         If result = ERRIO Then
  132.             continue = MsgBox(msgstr + Chr$(10) + "Reliability may suffer, continue?", MB_YESNO + MB_DEFBUTTON2 + MB_ICONSTOP, "PBOYSOUP.DLL: File format error")
  133.         End If
  134.         If result = ERRPARSE Then
  135.             continue = MsgBox(msgstr + Chr$(10) + "Reliability may suffer, continue?", MB_YESNO + MB_DEFBUTTON2 + MB_ICONSTOP, "PBOYSOUP.DLL: Incompatible file format")
  136.         End If
  137.         If continue = IDNO Then
  138.             frmmain.Hide     ' This should end sub main
  139.         End If
  140.     End If
  141. End Sub
  142.  
  143. Sub DoFolders ()
  144. Dim foldernum As Integer
  145. Dim foldername As String
  146. Dim folderfile As String
  147. Dim result As Integer
  148.  
  149.     screen.MousePointer = HourGlass
  150.     For foldernum = 1 To NUMFOLDERS
  151.         foldername = GetINI("Folders", "Name" + Format$(foldernum), "")
  152.         If foldername <> "" Then
  153.             folderfile = app.Path + "\FOLDER" + Format$(foldernum) + ".FOL"
  154.             result = LoadFolder(foldername, folderfile, "Paperboy folder")
  155.             DllErr result
  156.         End If
  157.     Next foldernum
  158.  
  159.     Call ShowAreas
  160.  
  161.     screen.MousePointer = default
  162. End Sub
  163.  
  164. Function endofheaders ()
  165. Dim firstline As Integer
  166.  
  167.     'Skip headers
  168.     firstline = 1
  169.     While firstline < GetNumLines() And Len(fixstr(GetLine(firstline))) > 0
  170.         firstline = firstline + 1
  171.     Wend
  172.  
  173.     'Skip the gap
  174.     While firstline < GetNumLines() And Len(fixstr(GetLine(firstline))) = 0
  175.         firstline = firstline + 1
  176.     Wend
  177.     
  178.     endofheaders = firstline
  179. End Function
  180.  
  181. Function extractusername (from As String) As String
  182. Dim username As String
  183. Dim pos As Integer
  184.  
  185.     username = Trim(from) 'Remove leading and trailing spaces
  186.  
  187. ' First type is of foo@bad.edu (john q. public)
  188.     If InStr(username, "(") > 0 Then
  189.         pos = InStr(username, "(")
  190.         ' Remove everything before (, up to )
  191.         username = Mid$(username, pos + 1)
  192.         username = Left$(username, InStr(username, ")") - 1)
  193.     ElseIf InStr(username, Chr(34)) > 0 Then
  194.     ' foo@bad.edu "john q. public"
  195.         pos = InStr(username, Chr(34))
  196.         username = Mid$(username, pos)
  197.         ' Truncate past second quote
  198.         username = Left$(username, InStr(username, Chr(34)) - 1)
  199.     ElseIf InStr(username, "<") > 0 Then
  200.     ' John Q. Public <foo@bad.edu>
  201.         pos = InStr(username, "<")
  202.         username = Left$(username, pos - 1)
  203.     ElseIf InStr(username, "@") > 0 Then
  204.     ' worst-case, john@bad.edu
  205.         pos = InStr(username, "@")
  206.         username = Left$(username, pos - 1)
  207.     End If
  208.     
  209.     ' If parsing gave us nothing, punt
  210.     username = Trim(username)
  211.     If Len(username) = 0 Then username = from
  212.     extractusername = username
  213. End Function
  214.  
  215. Function FileExists (fname As String) As Integer
  216. 'Dim fout As Integer
  217.     'fout = FreeFile
  218.     'On Error Resume Next
  219.     'Open fname For Input As fout
  220.     'If Err = 0 Then
  221.         'Close fout
  222.         'FileExists = 1
  223.     'Else
  224.         'FileExists = 0
  225.     'End If
  226.     If Dir$(fname) = "" Then FileExists = 0 Else FileExists = -1
  227. End Function
  228.  
  229. Function fixstr (ByVal az As Long) As String
  230. Static tempstr  As String * 1000
  231. Dim z As Integer
  232.  
  233. If az <> 0 Then
  234.     az = lstrcpy(tempstr, az)
  235.     z = InStr(tempstr, Chr(0)) 'Chop off null-terminator
  236.     If z > 0 Then fixstr = Left$(tempstr, z - 1) Else fixstr = tempstr
  237. Else fixstr = ""
  238. End If
  239. End Function
  240.  
  241. Function GetINI (ByVal section As String, ByVal key As String, ByVal defvalue As String) As String
  242. Dim result As Integer
  243. Dim newvalue As String
  244. Static hold As String * 200 'Holding place for returned string
  245.  
  246.     result = GetPrivateProfileString(section, key, "xYzZy", hold, 199, INIfile)
  247.     'Chop off null-terminator
  248.     result = InStr(hold, Chr(0))
  249.     If result > 0 Then newvalue = Left$(hold, result - 1) Else newvalue = hold
  250.  
  251.     If newvalue = "xYzZy" Then
  252.         ' Write default out to INI file so user knows what's going on
  253.         result = WritePrivateProfileString(section, key, defvalue, INIfile)
  254.         newvalue = defvalue
  255.     End If
  256.  
  257.     While Left$(newvalue, 1) = " "
  258.         newvalue = Mid$(newvalue, 2) 'Remove trailing spaces
  259.     Wend
  260.  
  261.     GetINI = newvalue
  262. End Function
  263.  
  264. Function intmax (ByVal a As Integer, ByVal b As Integer) As Integer
  265.     If a >= b Then intmax = a Else intmax = b
  266. End Function
  267.  
  268. Function intmin (ByVal a As Integer, ByVal b As Integer) As Integer
  269.     If a <= b Then intmin = a Else intmin = b
  270. End Function
  271.  
  272. Sub LoadMenuOptions ()
  273.  
  274.     If UCase$(GetINI("Display", "FixedPitch", "N")) = "N" Then
  275.         frmmain.mnufixedpitch.Checked = False
  276.     Else
  277.         frmmain.mnufixedpitch.Checked = True
  278.     End If
  279.  
  280.     If UCase$(GetINI("Display", "ShowHeaders", "N")) = "N" Then
  281.         frmmain.mnushowheaders.Checked = False
  282.     Else
  283.         frmmain.mnushowheaders.Checked = True
  284.     End If
  285.     
  286.     If UCase$(GetINI("Display", "ShowLengths", "N")) = "N" Then
  287.         frmmain.mnushowlengths.Checked = False
  288.     Else
  289.         frmmain.mnushowlengths.Checked = True
  290.     End If
  291.  
  292. End Sub
  293.  
  294. Sub Main ()
  295.     Dim lpstr As Long
  296.     Dim result As Integer
  297.     Dim hold As String * 100
  298.  
  299.     PaperboyVersion = "2.06"
  300.  
  301.     ' Go to Paperboy's EXE directory
  302.     ChDir app.Path
  303.     ChDrive app.Path
  304.  
  305.     If app.PrevInstance = True Then
  306.         MsgBox "Only one Paperboy can be active.", MB_ICONSTOP, "Sorry"
  307.         End
  308.     End If
  309.  
  310.     ' Fire up the DLL
  311.     result = InitSOUPDLL()
  312.     If result <> 0 Then
  313.         MsgBox "Cannot initialize PBOYSOUP.DLL", MB_ICONEXCLAMATION, "InitSOUPDLL()"
  314.         End
  315.     End If
  316.  
  317.     INIfile = "PAPERBOY.INI"
  318.     'INIfile = App.Path + "\PAPERBOY.INI"
  319.     SetINI "Paperboy", "Copyright", "(C) 1995, Michael H. Vartanian (vart@clark.net)"
  320.     SetINI "Paperboy", "License", "Paperboy is protected by the GNU public license, see the file COPYING included with Paperboy"
  321.  
  322.     'Check Version
  323.     If MajorVersion() <> 2 Or MinorVersion() <> 6 Then
  324.         MsgBox "Wrong version of PBOYSOUP.DLL", MB_ICONSTOP, "Installation Error"
  325.         End
  326.     End If
  327.     
  328.     If GetINI("Window", "Maximized", "N") = "N" Then
  329.         frmmain.WindowState = NORMAL
  330.     Else
  331.         frmmain.WindowState = MAXIMIZED
  332.     End If
  333.  
  334.     Call LoadMenuOptions
  335.  
  336.     frmmain.Height = Val(GetINI("Window", "Height", screen.Height * .9))
  337.     frmmain.Width = Val(GetINI("Window", "Width", screen.Width * .9))
  338.     frmmain.Left = Val(GetINI("Window", "Left", (screen.Width - frmmain.Width) \ 2))
  339.     frmmain.Top = Val(GetINI("Window", "Top", (screen.Height - frmmain.Height) \ 2))
  340.     
  341.     frmmain!lstareas.FontName = GetINI("Fonts", "GroupsName", "Arial")
  342.     frmmain!lstareas.FontSize = Val(GetINI("Fonts", "GroupsSize", "10"))
  343.     frmmain!lstsubjects.FontName = GetINI("Fonts", "SubjName", "Arial")
  344.     frmmain!lstsubjects.FontSize = Val(GetINI("Fonts", "SubjSize", "10"))
  345.     
  346.     ' Handle Folders
  347.     Call DoFolders
  348.  
  349.     ' If command-line, assume it's the AREAS filename
  350.     If Len(Command$) > 1 Then
  351.         OpenAreas (Command$)
  352.     End If
  353.  
  354.     If FileExists("REPLIES") Then
  355.         MsgBox "Don't forget to upload your replies packet." + Chr(13) + Chr(10) + "(pkzip UPLOADME.ZIP REPLIES. PB*.MSG)", MB_OK + MB_ICONINFORMATION, "REPLIES file found!"
  356.     End If
  357.  
  358.     frmmain.Show Modal
  359.     ' frmmain has quit, shut down
  360.  
  361.     SetINI "Files", "LastGroupRead", Format$(Group)
  362.     SetINI "Files", "LastMessageRead", Format$(Message)
  363.     End
  364. End Sub
  365.  
  366. Sub OpenAreas (filename As String)
  367. Dim result, continue, count As Integer
  368. Dim workdir As String
  369. Dim unzip As String
  370. Dim x As Integer
  371.  
  372.     frmmain.mnuFOPEN.Enabled = False
  373.  
  374.     screen.MousePointer = HourGlass
  375.  
  376.     If UCase$(Right$(filename, 3)) = "ZIP" Then
  377.     ' We got a ZIP packet to deal with
  378.         workdir = GetINI("Files", "Packet Directory", app.Path)
  379.         unzip = GetINI("Files", "Unzipper", "pkunzip -o -ere")
  380.         unzip = unzip + " " + filename + " " + workdir
  381.         'ChDrive workdir
  382.         'ChDir workdir
  383.         x = Shell(unzip, 6)
  384.         MsgBox "Press when complete...", 0, unzip
  385.         filename = workdir + "\AREAS."
  386.         If Not FileExists(filename) Then
  387.             frmmain.mnuFOPEN.Enabled = True
  388.             MsgBox "Couldn't extract packet", 0, "Error during unzip"
  389.             screen.MousePointer = default
  390.             Exit Sub
  391.         End If
  392.     End If
  393.  
  394.     result = LoadAreas(filename)
  395.     screen.MousePointer = default
  396.     
  397.     DllErr result
  398.     
  399.     If GetInfo() = 0 Then
  400.         ' We got something urgent to show
  401.         frminfo.Show 1
  402.     End If
  403.  
  404.     Call ShowAreas
  405.     
  406. End Sub
  407.  
  408. Sub SaveFiletoFolder (fname As String, folder As String)
  409. Dim foldernum As Integer
  410. Dim folderfile As String
  411. Dim foldername As String
  412. Dim filenum As Integer
  413. Dim textline As String
  414. Dim result As Integer
  415.  
  416.     folderfile = ""
  417.     For foldernum = 1 To NUMFOLDERS
  418.         foldername = GetINI("Folders", "Name" + Format$(foldernum), "")
  419.         If foldername = folder Then
  420.             folderfile = app.Path + "\FOLDER" + Format$(foldernum) + ".FOL"
  421.         End If
  422.     Next foldernum
  423.     
  424.     If folderfile <> "" Then
  425.     ' Save file fname to folder folderfile
  426.         Call CreateNewMsg
  427.         filenum = FreeFile
  428.         Open fname For Input As filenum
  429.         While Not EOF(filenum)
  430.             Line Input #filenum, textline
  431.             result = AddLineToMsg(textline)
  432.         Wend
  433.         Close filenum
  434.         result = SaveMsgToFolder(folderfile)
  435.         DllErr result
  436.         'MsgBox "Saved to " + folderfile
  437.     End If
  438.  
  439.     ' Reread folders
  440.     DoFolders
  441.  
  442. End Sub
  443.  
  444. Sub SetINI (ByVal section As String, ByVal key As String, ByVal value As String)
  445.     'Sets an INI attribute
  446. Dim result As Integer
  447.  
  448.     INIfile = "PAPERBOY.INI"
  449.     While Left$(value, 1) = " "
  450.         value = Mid$(value, 2) 'Remove trailing spaces
  451.     Wend
  452.     result = WritePrivateProfileString(section, key, value, INIfile)
  453.  
  454. End Sub
  455.  
  456. Sub ShowAreas ()
  457. Dim count As Integer
  458. Dim groupname As String
  459. Dim hold, grp, msg As Integer
  460.  
  461.     frmmain.lstareas.Clear
  462.     frmmain.lstsubjects.Clear
  463.     For count = 1 To GetNumAreas()
  464.         groupname = fixstr(GetAreaName(count))
  465.         frmmain.lstareas.AddItem groupname
  466.     Next count
  467.     frmmain.lstareas.Enabled = True
  468.     grp = Val(GetINI("Files", "LastGroupRead", "0")) - 1
  469.     msg = Val(GetINI("Files", "LastMessageRead", "0")) - 1
  470.     If Persist = True Then
  471.         Persist = False
  472.         hold = MsgBox("Should I put you at the last read message?", MB_ICONQUESTION Or MB_YESNO, "Previously viewed packet")
  473.         If hold = IDYES Then
  474.             If grp >= 0 Then frmmain.lstareas.ListIndex = grp
  475.             If msg >= 0 Then frmmain.lstsubjects.ListIndex = msg
  476.         End If
  477.     End If
  478. End Sub
  479.  
  480. Function stripfilename (filename As String) As String
  481. Dim lastbackslash, p As Integer
  482.  
  483.     For p = 1 To Len(filename)
  484.         If Mid$(filename, p, 1) = "\" Then lastbackslash = p
  485.     Next p
  486.     
  487.     If lastbackslash > 1 Then
  488.         stripfilename = Left$(filename, lastbackslash - 1)
  489.     Else
  490.         stripfilename = "\"
  491.     End If
  492. End Function
  493.  
  494.